/**
 * Copyright (C) 2010, 2011 Neofonie GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package eu.dicodeproject.analysis.examples;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathFilter;
import org.apache.mahout.utils.io.ChunkedWriter;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.mbox.MboxParser;
import org.xml.sax.SAXException;

/**
 * Converts a directory containing unzipped mail archives in mbox format to a
 * sequencefiles.
 * 
 * Key is original filename with an id increasing with each email seen appended.
 * Value is the plain e-mail including header information.
 * */
public class MailArchiveToSequenceFile implements PathFilter {

  private final String prefix;
  private final ChunkedWriter writer;
  private final Charset charset;
  private final MailContentHandler handler;
  private final FileSystem fs;
  private final Configuration conf;

  public MailArchiveToSequenceFile(Configuration conf, String prefix, ChunkedWriter writer, Charset charset)
      throws IOException {
    this(conf, prefix, writer, charset, new MailHandler(writer));
  }

  public MailArchiveToSequenceFile(Configuration conf, String prefix, ChunkedWriter writer, Charset charset,
      MailContentHandler handler) throws IOException {
    this.prefix = prefix;
    this.writer = writer;
    this.charset = charset;
    this.handler = handler;
    this.fs = FileSystem.get(conf);
    this.conf = conf;
  }

  /**
   * Accepts all files in a directory, splits each file into individual mails
   * and concatenates them - each prefixed with the mail's message id.
   * 
   * TODO filter for headers vs. body
   * */
  @Override
  public boolean accept(Path current) {
    try {
      FileStatus[] fstatus = fs.listStatus(current);
      for (FileStatus fst : fstatus) {
	if (fst.isDir()) {
	  this.fs.listStatus(fst.getPath(),
	      new MailArchiveToSequenceFile(conf, prefix + File.separator + current.getName(), writer, charset));
	} else {
	  InputStream stream = null;
	  try {
	    MboxParser parser = new MboxParser();
	    Metadata meta = new Metadata();
	    stream = fs.open(fst.getPath());
	    this.handler.setPrefix(this.prefix + current.getName());
	    parser.parse(stream, this.handler, meta);
	  } catch (FileNotFoundException e) {
	    // TODO: report exceptions before continue
	  } catch (IOException e) {
	    // TODO: report exceptions and continue
	  } catch (TikaException e) {
	    // TODO report and continue
	  } catch (SAXException e) {
	    // TODO report and continue
	  } finally {
	    try {
	      if (stream != null) {
		stream.close();
	      }
	    } catch (Exception e) {
	      // Nothing we can do here, really.
	    }
	  }
	}
      }
    } catch (IOException e) {
      throw new IllegalStateException(e);
    }

    return false;
  }

}
